package com.zyht.common.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.wx.core.process.HttpMethod;
import com.wx.core.process.JEEWeiXinX509TrustManager;

/**
 * 描述：http相关工具<br>
 * 作者：ZRB <br>
 * 修改日期：2017年6月21日下午3:04:18 <br>
 * @see StandardCharsets
 */
public final class HttpUtils {
	
	private static final int HTTP_CONNECTION_TIMEOUT = 3000;
	
	private static final int HTTP_SO_TIMEOUT = 5000;
	
	private static final Logger logger = LoggerFactory.getLogger(HttpUtils.class);
	
	public static String post(String urlvalue, Map<String, String> paras, String charset) {
    	HttpClient http = new HttpClient();
		HttpConnectionManagerParams managerParams = http.getHttpConnectionManager().getParams();
        // 设置连接超时时间(单位毫秒)
        managerParams.setConnectionTimeout(HTTP_CONNECTION_TIMEOUT);
        // 设置读数据超时时间(单位毫秒)
        managerParams.setSoTimeout(HTTP_SO_TIMEOUT);
        PostMethod method = new PostMethod(urlvalue);
		method.getParams().setHttpElementCharset(charset);
		method.getParams().setContentCharset(charset);
		method.getParams().setCredentialCharset(charset);
        for (String key : paras.keySet()) {
            method.addParameter(key, paras.get(key));
            if(logger.isInfoEnabled())
            	logger.info(key + " : " + paras.get(key));
        }
        String result = "";
        try {
            http.executeMethod(method);
            result = method.getResponseBodyAsString();
            if(logger.isDebugEnabled()){
            	logger.debug("Http result is: \n"+result);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
	
	/**
	 * 方法名称: post<br>
	 * 描述：发送utf-8的post请求
	 * 作者: ZRB
	 * 修改日期：2017年6月21日下午3:05:35
	 * @param urlvalue
	 * @param paras
	 * @return
	 *
	 */
    public static String post(String urlvalue, Map<String, String> paras) {
    	return post(urlvalue, paras, StandardCharsets.UTF_8.name());
    }
    
    public static String get(String urlvalue) {
        StringBuilder builder = new StringBuilder();
        try {
            URL url = new URL(urlvalue);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8));
            urlConnection.setReadTimeout(HTTP_CONNECTION_TIMEOUT);
            urlConnection.setConnectTimeout(HTTP_SO_TIMEOUT);
            String line = in.readLine();
            while (line != null) {
            	builder.append(line);
                line = in.readLine();
            }
        } catch (SSLHandshakeException d) {
            d.printStackTrace();
            logger.error("SSL握手异常：" + d.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("Http请求异常：" + e.getMessage());
        }
        return builder.toString();
    }

    /**
     * @author: zrb
     * 修改时间：2015年8月7日 - 上午11:25:25<br/>
     * 功能说明：发送http的json数据<br/>
     * @param url
     * @param json
     * @return 回调结果
     * @throws IOException 
     * @throws Exception
     */
    public static final String post(String url, String json) throws IOException{
		HttpClient client = new HttpClient();
		HttpConnectionManagerParams params = client.getHttpConnectionManager().getParams();
		params.setConnectionTimeout(5000);
		params.setSoTimeout(5000);
		params.setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");
		client.getHttpConnectionManager().setParams(params);
		PostMethod post = new PostMethod(url);
		StringRequestEntity strRequest = new StringRequestEntity(json, "application/json", StandardCharsets.UTF_8.displayName());
		post.setRequestEntity(strRequest);
		if(logger.isInfoEnabled()){
			logger.info("Http请求["+url+"]发出请求...");
		}
		int code = client.executeMethod(post);
		if(code==HttpStatus.SC_OK){
			String charset = post.getResponseCharSet().toLowerCase();
			String postResponse = post.getResponseBodyAsString();
			postResponse = new String (postResponse.getBytes(charset), StandardCharsets.UTF_8);
			post.releaseConnection();
			if(logger.isDebugEnabled()){
				logger.debug("请求响应正文是：" + postResponse);
			}
			return postResponse;
		}
		post.releaseConnection();
		throw new IOException("请求状态码返回：" + code);
	}
    
    @SuppressWarnings("unchecked")
	public static final Map<String, Object> postFile(String uri, Part[] parts){
		HttpClient client = new HttpClient();
		HttpConnectionManagerParams params = client.getHttpConnectionManager().getParams();
		params.setConnectionTimeout(5000);
		params.setSoTimeout(5000);
		client.getHttpConnectionManager().setParams(params);
		PostMethod post = new PostMethod(uri);
		try {
			MultipartRequestEntity multipartEntity = new MultipartRequestEntity(parts, post.getParams());
			post.setRequestEntity(multipartEntity);
			int code = client.executeMethod(post);
			if(code==HttpStatus.SC_OK){
				String resultStr = post.getResponseBodyAsString();
				return JSON.toJavaObject(JSON.parseObject(resultStr), Map.class);
			}else{
				throw new HttpException("http响应异常："+code);
			}
		}catch(Exception e){
			e.printStackTrace();
			HashMap<String, Object> result = new HashMap<String, Object>();
			result.put("error", e.getMessage());
			return result;
		}
	}
    
    /**
     * 方法名称: sendHttpsRequest<br>
     * 描述：https请求
     * 作者: ZRB
     * 修改日期：2017年6月21日下午3:29:22
     * @param requestUrl
     * @param requestMethod
     * @param paramStr
     * @return
     * 
     * @see HttpMethod
     */
    public static String sendHttpsRequest(String requestUrl, String requestMethod, String paramStr) {
		String result = null;
		try {
			TrustManager[] tm = { new JEEWeiXinX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(ssf);
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod(requestMethod);
			if (null != paramStr) {
				OutputStream outputStream = conn.getOutputStream();
				outputStream.write(paramStr.getBytes(StandardCharsets.UTF_8));
				outputStream.close();
			}
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			inputStream = null;
			conn.disconnect();
			return buffer.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return result;
		} 
	}
    
    /**
     * 方法名称: httpsPost<br>
     * 描述：
     * 作者: ZRB
     * 修改日期：2017年6月21日下午3:32:10
     * @param requestUrl
     * @param paramStr
     * @return
     * @see com.wx.util.HttpUtils.sendHttpsRequest
     */
    public static String httpsPost(String requestUrl, String paramStr){
    	return sendHttpsRequest(requestUrl, HttpMethod.POST, paramStr);
    }
    
    /**
     * 方法名称: httpsGet<br>
     * 描述：
     * 作者: ZRB
     * 修改日期：2017年6月21日下午3:32:10
     * @param requestUrl
     * @param paramStr
     * @return
     * @see com.wx.util.HttpUtils.sendHttpsRequest
     */
    public static String httpsGet(String requestUrl){
    	return sendHttpsRequest(requestUrl, HttpMethod.GET, null);
    }
}
